<?php

namespace app\component\easyWechat;

use app\common\OpenInfoBean;
use app\models\OpenInfo;
use app\repository\OpenInfoRepository;
use EasyWeChat\Factory;
use EasyWeChat\OfficialAccount\Application;
use Yii;
use yii\base\Component;

class officialAccount extends Component
{
    public string $appid;
    public string $secret;
    public string $token;
    public string $aesKey;
    public string $miniAppid;
    public Application $app;

    /**
     * $app 在所有相关公众号的文档都是指 Factory::officialAccount 得到的实例。
     */
    public function init()
    {
        parent::init();
        $config = [
            'app_id' => $this->appid,
            'secret' => $this->secret,
            // 指定 API 调用返回结果的类型：array(default)/collection/object/raw/自定义类名
            'response_type' => 'array',
        ];

        $this->app = Factory::officialAccount($config);
    }

    /**
     * @return \Symfony\Component\HttpFoundation\Response
     * @throws \EasyWeChat\Kernel\Exceptions\BadRequestException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     * @throws \ReflectionException
     */
    public function accept(): \Symfony\Component\HttpFoundation\Response
    {
        $this->app->server->push(function ($message) {
            switch ($message['MsgType']) {
                case 'event':
                    $this->eventHandles($message);
                    break;
                case 'text':
                    return '收到文字消息';
                    break;
                case 'image':
                    return '收到图片消息';
                    break;
                case 'voice':
                    return '收到语音消息';
                    break;
                case 'video':
                    return '收到视频消息';
                    break;
                case 'location':
                    return '收到坐标消息';
                    break;
                case 'link':
                    return '收到链接消息';
                    break;
                case 'file':
                    return '收到文件消息';
                default:
                    return '收到其它消息';
                    break;
            }
        });

        $response = $this->app->server->serve();
        return $response->send();
    }

    /**
     * 事件消息
     *
     * @param $message
     * @return string
     */
    public function eventHandles($message): string
    {
        Yii::info('公众号消息：' . json_encode(['message' => $message]), 'official_account');

        $openId = $message['FromUserName'];
        $user = [];
        try {
            $user = $this->app->user->get($openId);
        } catch (\Exception $e) {
            Yii::info('公众号消息：' . json_encode(['message' => $e->getMessage()]), 'official_account');
        }
        Yii::info('公众号消息：' . json_encode(['user' => $user]), 'official_account');
        if (!$user) {
            return 'success';
        }

        if ($message['Event'] == 'subscribe') {//关注公众号
            $this->follow($openId, $user);

            return 'success';
        } elseif ($message['Event'] == 'unsubscribe') {//取消关注公众号
            $this->unfollow($openId, $user['subscribe']);

            return 'success';
        }

        return 'success';
    }

    public function follow($openId, $user)
    {
        $openInfo = OpenInfoRepository::getInstance()->getOfficialAccountOne($this->appid, $openId);
        if (!$openInfo) {
            $openInfo = new OpenInfo();
        }
        $openInfo->openid = $openId;
        $openInfo->third_type = OpenInfoBean::THIRD_TYPE_OFFICIAL;
        $openInfo->app_id = $this->appid;
        $openInfo->nick_name = $user['nickname'];
        $openInfo->gender = $user['sex'];
        $openInfo->province = $user['province'];
        $openInfo->city = $user['city'];
        $openInfo->country = $user['country'];
        $openInfo->avatar_url = $user['headimgurl'];
        $openInfo->union_id = $user['unionid'];;
        $openInfo->subscribe = $user['subscribe'];
        $openInfo->subscribe_time = $user['subscribe_time'];
        $openInfo->accept_status = 1;//接收通知
        $openInfo->add_time = $openInfo->add_time ?? time();
        $openInfo->last_time = time();
        $openInfo->save();
    }

    public function buildConfig()
    {
        return $this->app->jssdk->buildConfig(
            ['updateAppMessageShareData', 'updateTimelineShareData'],
            $debug = false,
            $beta = false,
            $json = true, $openTagList = []
            );
    }


}